package org.jeecg.modules.solitaire_app.wxpay.v3;

import cn.hutool.json.JSONUtil;
import com.wechat.pay.contrib.apache.httpclient.util.AesUtil;
import org.apache.commons.codec.binary.Base64;

import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.*;
import java.security.spec.InvalidKeySpecException;

public class Util {

    /**
       * Util工具类方法
       * 获取一定长度的随机字符串，范围0-9，a-z
       * @param length：指定字符串长度
       * @return 一定长度的随机字符串
       */
    private static final String ENCODING = "UTF-8";
    private static final String SIGNATURE_ALGORITHM = "SHA256withRSA";

  /**
   * SHA256WithRSA签名
   * @param data
   * @param privateKey
   * @return
   * @throws NoSuchAlgorithmException
   * @throws InvalidKeySpecException
   * @throws InvalidKeyException
   * @throws SignatureException
   * @throws UnsupportedEncodingException
   */
  public static byte[] sign256(String data, PrivateKey privateKey) throws NoSuchAlgorithmException, InvalidKeySpecException, InvalidKeyException,
          SignatureException, UnsupportedEncodingException {

    Signature signature = Signature.getInstance(SIGNATURE_ALGORITHM);

    signature.initSign(privateKey);

    signature.update(data.getBytes(ENCODING));

    return signature.sign();
  }

  public static boolean verify256(String data, byte[] sign, PublicKey publicKey){
    if(data == null || sign == null || publicKey == null){
      return false;
    }

    try {
      Signature signetcheck = Signature.getInstance(SIGNATURE_ALGORITHM);
      signetcheck.initVerify(publicKey);
      signetcheck.update(data.getBytes("UTF-8"));
      return signetcheck.verify(sign);
    } catch (Exception e) {
      return false;
    }
  }

  /**
   * 二进制数据编码为BASE64字符串
   * @param bytes
   * @return
   */
  public static String encodeBase64(byte[] bytes){
    return new String(Base64.encodeBase64(bytes));
  }

  /**
   * BASE64解码
   * @param bytes
   * @return
   */
  public static byte[] decodeBase64(byte[] bytes) {
    byte[] result = null;
    try {
      result = Base64.decodeBase64(bytes);
    } catch (Exception e) {
      return null;
    }
    return result;
  }

    /**
     * 处理返回对象
     *
     * @param request
     * @return
     */
   public static String readData(HttpServletRequest request) {
        BufferedReader br = null;
        try {
            StringBuilder result = new StringBuilder();
            br = request.getReader();
            for (String line; (line = br.readLine()) != null; ) {
                if (result.length() > 0) {
                    result.append("\n");
                }
                result.append(line);
            }
            return result.toString();
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * v3 支付异步通知验证签名
     *
     * @param body 异步通知密文
     * @param key  api 密钥
     * @return 异步通知明文
     * @throws Exception 异常信息
     */
   public static String verifyNotify(String body, String key) throws Exception {
        // 获取平台证书序列号
        cn.hutool.json.JSONObject resultObject = JSONUtil.parseObj(body);
        cn.hutool.json.JSONObject resource = resultObject.getJSONObject("resource");
        String cipherText = resource.getStr("ciphertext");
        String nonceStr = resource.getStr("nonce");
        String associatedData = resource.getStr("associated_data");
        AesUtil aesUtil = new AesUtil(key.getBytes(StandardCharsets.UTF_8));
        // 密文解密
        return aesUtil.decryptToString(
                associatedData.getBytes(StandardCharsets.UTF_8),
                nonceStr.getBytes(StandardCharsets.UTF_8),
                cipherText
        );
    }
}
